package voip;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Scanner;
import java.util.Calendar;

public class SDPparser {
	private final static int MAXARRAY = 10; 
	/*
	 *  Session description
	    v=  (protocol version)
        o=  (originator and session identifier)
        s=  (session name)
        i=* (session information)
        u=* (URI of description)
        e=* (email address)
        p=* (phone number)
        c=* (connection information not required if included in all media)
        b=* (zero or more bandwidth information lines)
        One or more time descriptions ("t=" and "r=" lines; see below)
        z=* (time zone adjustments)
        k=* (encryption key)
        a=* (zero or more session attribute lines)
        Zero or more media descriptions

        Time description
        t=  (time the session is active)
        r=* (zero or more repeat times)

        Media description, if present
        m=  (media name and transport address)
        i=* (media title)
        c=* (connection information optional if included at
             session level)
        b=* (zero or more bandwidth information lines)
        k=* (encryption key)
        a=* (zero or more media attribute lines)
	 */
	private String version;
	private String originator;
	private String session_name;
	private String session_info;
	private String uri;
	private String email;
	private String phone;
	private String connection;
	private String bandwidth;
	private String []time = new String[MAXARRAY];
	private String []time_repeat = new String[MAXARRAY];
	private String time_zone;
	private String encryption_key;
	private String []session_attribute = new String[MAXARRAY];
	private String []media_name = new String[MAXARRAY];
	private String []media_title = new String[MAXARRAY];
	private String []media_connection = new String[MAXARRAY];
	private String []media_bandwidth = new String[MAXARRAY];
	private String []media_encryption = new String[MAXARRAY];
	private String []media_attribute = new String[MAXARRAY];
	private String SDPbody;
	
	long theID;
	InetAddress hostAddr;
	
	private int timeDescCount;
	private int sessAttCount;
	private int mediaDescCount;
	private int mediaAttCount;
	private int cnt;
	
	public SDPparser(){
		version = "";
		originator = "";
		session_name = "";
		session_info = "";
		uri = "";
		email = "";
		phone = "";
		connection = "";
		bandwidth = "";
		time_zone = "";
		encryption_key = "";
		SDPbody = "";

		theID = 0;
		timeDescCount = 0;
		sessAttCount = 0;
		mediaDescCount = 0;
		mediaAttCount = 0;
		cnt = 0;
		
		getHostAddress();
	}
	
	public void resetCount(){
		timeDescCount = 0;
		sessAttCount = 0;
		mediaDescCount = 0;
		mediaAttCount = 0;
		cnt = 0;		
	}
	
	public void generateID(){
		Calendar theCalendar = Calendar.getInstance();
		theID = theCalendar.getTimeInMillis();

	}
	
	public void getHostAddress(){
		try {
			hostAddr = InetAddress.getLocalHost();
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public String getVersion(String in){
		int sidx;
		String strbuf = "";
		sidx = in.indexOf("v=");
		if(sidx != -1)
			strbuf = in.substring(sidx+2);
		return strbuf;
	}
	
	public String getOriginator(String in){
		int sidx;
		String strbuf = "";
		sidx = in.indexOf("o=");
		if(sidx != -1)
			strbuf = in.substring(sidx+2);
		return strbuf;
	}

	public String getSessionName(String in){
		int sidx;
		String strbuf = "";
		sidx = in.indexOf("s=");
		if(sidx != -1)
			strbuf = in.substring(sidx+2);
		return strbuf;
	}

	public String getSessionInformation(String in){
		int sidx;
		String strbuf = "";
		sidx = in.indexOf("i=");
		if(sidx != -1)
			strbuf = in.substring(sidx+2);
		return strbuf;
	}

	public String getUri(String in){
		int sidx;
		String strbuf = "";
		sidx = in.indexOf("u=");
		if(sidx != -1)
			strbuf = in.substring(sidx+2);
		return strbuf;
	}

	public String getEmail(String in){
		int sidx;
		String strbuf = "";
		sidx = in.indexOf("e=");
		if(sidx != -1)
			strbuf = in.substring(sidx+2);
		return strbuf;
	}

	public String getPhone(String in){
		int sidx;
		String strbuf = "";
		sidx = in.indexOf("p=");
		if(sidx != -1)
			strbuf = in.substring(sidx+2);
		return strbuf;
	}
	
	public String getBandwidth(String in){
		int sidx;
		String strbuf = "";
		sidx = in.indexOf("b=");
		if(sidx != -1)
			strbuf = in.substring(sidx+2);
		return strbuf;
	}
	
	public String getConnectionInformation(String in){
		int sidx;
		String strbuf = "";
		sidx = in.indexOf("c=");
		if(sidx != -1)
			strbuf = in.substring(sidx+2);
		return strbuf;
	}

	public String getActiveTime(String in){
		int sidx;
		String strbuf = "";
		sidx = in.indexOf("t=");
		if(sidx != -1)
			strbuf = in.substring(sidx+2);
		return strbuf;
	}

	public String getEncryptionKey(String in){
		int sidx;
		String strbuf = "";
		sidx = in.indexOf("k=");
		if(sidx != -1)
			strbuf = in.substring(sidx+2);
		return strbuf;
	}

	public String getSessionAttribute(String in){
		int sidx;
		String strbuf = "";
		sidx = in.indexOf("a=");
		if(sidx != -1)
			strbuf = in.substring(sidx+2);
		return strbuf;
	}
	
	public String getTimeZone(String in){
		int sidx;
		String strbuf = "";
		sidx = in.indexOf("z=");
		if(sidx != -1)
			strbuf = in.substring(sidx+2);
		return strbuf;
	}

	public String getRepeatTime(String in){
		int sidx;
		String strbuf = "";
		sidx = in.indexOf("r=");
		if(sidx != -1)
			strbuf = in.substring(sidx+2);
		return strbuf;
	}
	
	public String getMediaName(String in){
		int sidx;
		String strbuf = "";
		sidx = in.indexOf("m=");
		if(sidx != -1)
			strbuf = in.substring(sidx+2);
		return strbuf;
	}

	public String getMediaTitle(String in){
		int sidx;
		String strbuf = "";
		sidx = in.indexOf("i=");
		if(sidx != -1)
			strbuf = in.substring(sidx+2);
		return strbuf;
	}

	public String getMediaEncryptionKey(String in){
		int sidx;
		String strbuf = "";
		sidx = in.indexOf("k=");
		if(sidx != -1)
			strbuf = in.substring(sidx+2);
		return strbuf;
	}
	
	public String getMediaAttribute(String in){
		int sidx;
		String strbuf = "";
		sidx = in.indexOf("a=");
		if(sidx != -1)
			strbuf = in.substring(sidx+2);
		return strbuf;
	}
	
	public void setVersion(String in){
		version = "v=" + in + "\r\n";
	}
	
	public void setOriginator(String in){
		originator = "o=" + in + "\r\n";
	}

	public void setSessionName(String in){
		session_name = "s=" + in + "\r\n";
	}

	public void setSessionInformation(String in){
		session_info = "i=" + in + "\r\n";
	}

	public void setUri(String in){
		uri = "u=" + in + "\r\n";
	}

	public void setEmail(String in){
		email = "e=" + in + "\r\n";
	}

	public void setPhone(String in){
		phone = "p=" + in + "\r\n";
	}

	public void setBandwidth(String in){
		bandwidth = "b=" + in + "\r\n";
	}
	
	public void setConnectionInformation(String in){
		connection = "c=" + in + "\r\n";
	}

	public void setActiveTime(String in){
		if(timeDescCount<MAXARRAY){
			time[timeDescCount] = "t=" + in + "\r\n";
			timeDescCount++;
		}
	}

	public void setRepeatTime(String in){
		time_repeat[timeDescCount] = "r=" + in + "\r\n";
	}

	public void setTimeZone(String in){
		time_zone = "z=" + in + "\r\n";
	}
	
	public void setEncryptionKey(String in){
		encryption_key = "k=" + in + "\r\n";
	}

	public void setSessionAttribute(String in){
		if(sessAttCount<MAXARRAY){
			session_attribute[sessAttCount] = "a=" + in + "\r\n";
			sessAttCount++;
		}
	}
	
	public void setMediaName(String in){
		if(mediaDescCount<MAXARRAY){
			media_name[mediaDescCount] = "m=" + in + "\r\n";
			mediaDescCount++;
		}
	}

	public void setMediaTitle(String in){
		media_title[mediaDescCount] = "i=" + in + "\r\n";
	}

	public void setMediaConnection(String in){
		media_connection[mediaDescCount] = "c=" + in + "\r\n";
	}
	
	public void setMediaBandwidth(String in){
		media_bandwidth[mediaDescCount] = "b=" + in + "\r\n";
	}
	
	public void setMediaEncryptionKey(String in){
		media_encryption[mediaDescCount] = "k=" + in + "\r\n";
	}
	
	public void setMediaAttribute(String in){
		if(mediaAttCount<MAXARRAY){
			media_attribute[mediaAttCount] = "a=" + in + "\r\n";
			mediaAttCount++;
		}
	}

	public String setSDPbody(){
		SDPbody = version
				+ originator
				+ session_name
				+ session_info
				+ uri
				+ email
				+ phone
				+ connection
				+ bandwidth;
		
		for(cnt=0; cnt<timeDescCount; cnt++){
			if(time[cnt] != null)
				SDPbody = SDPbody.concat(time[cnt]);
			if(time_repeat[cnt] != null)
				SDPbody = SDPbody.concat(time_repeat[cnt]);
		}
		
		if(time_zone != null)
			SDPbody = SDPbody.concat(time_zone);

		if(encryption_key != null)
			SDPbody = SDPbody.concat(encryption_key);
		
		for(cnt=0; cnt<sessAttCount; cnt++){
			if(session_attribute[cnt] != null)
				SDPbody = SDPbody.concat(session_attribute[cnt]);
		}
		
		for(cnt=0; cnt<mediaDescCount; cnt++){
			if(media_name[cnt] != null)
				SDPbody = SDPbody.concat(media_name[cnt]);
			if(media_title[cnt] != null)
				SDPbody = SDPbody.concat(media_title[cnt]);
			if(media_connection[cnt] != null)
				SDPbody = SDPbody.concat(media_connection[cnt]);
			if(media_bandwidth[cnt] != null)
				SDPbody = SDPbody.concat(media_bandwidth[cnt]);
			if(media_encryption[cnt] != null)
				SDPbody = SDPbody.concat(media_encryption[cnt]);
		}
		
		for(cnt=0; cnt<mediaAttCount; cnt++){
			if(media_attribute[cnt] != null)
				SDPbody = SDPbody.concat(media_attribute[cnt]);
		}
		return SDPbody;

	}
	
	public void parseSDP (String in){       
		Scanner scanner = new Scanner(in);
		while (scanner.hasNextLine()) {
			String line = scanner.nextLine();
			if(line.startsWith("v=o") == true){
				setVersion(getVersion(line));
			}
			else if(line.startsWith("o=") == true){
				setOriginator(getOriginator(line));
			}
			else if(line.startsWith("s=") == true){
				setSessionName(getSessionName(line));
			}
			else if(line.startsWith("i=") == true){
				setSessionInformation(getSessionInformation(line));
			}
			else if(line.startsWith("u=") == true){
				setUri(getUri(line));
			}
			else if(line.startsWith("e=") == true){
				setEmail(getEmail(line));
			}
			else if(line.startsWith("p=") == true){
				setPhone(getPhone(line));
			}
			else if(line.startsWith("b") == true){
				setBandwidth(getBandwidth(line));
			}
			else if(line.startsWith("t=") == true){
				setActiveTime(getActiveTime(line));
			}
			else if(line.startsWith("r=") == true){
				setRepeatTime(getRepeatTime(line));
			}
			else if(line.startsWith("z=") == true){
				setTimeZone(getTimeZone(line));
			}
			else if(line.startsWith("k=") == true){
				setEncryptionKey(getEncryptionKey(line));
			}
			else if(line.startsWith("a=") == true){
				setSessionAttribute(getSessionAttribute(line));
			}
			else if(line.startsWith("m=") == true){
				setMediaName(getMediaName(line));
				while (scanner.hasNextLine()) {
					line = scanner.nextLine();
					if(line.startsWith("i=") == true){
						setMediaTitle(getMediaTitle(line));
					}
					else if(line.startsWith("c=") == true){
						setMediaConnection(getConnectionInformation(line));						
					}
					else if(line.startsWith("b=") == true){
						setMediaBandwidth(getBandwidth(line));
					}
					else if(line.startsWith("k=") == true){
						setMediaEncryptionKey(getMediaEncryptionKey(line));
					}
					else if(line.startsWith("a=") == true){
						setMediaAttribute(getMediaAttribute(line));
					}
				}
			}
		}
	}
	
	public String testSDPreply(){
	
		String strbuf = "";
		
		resetCount();
		generateID();
		setVersion("0");
		
		strbuf = "root " + theID + " " + theID + " IN IP4 " + hostAddr;
		setOriginator(strbuf);

		setSessionName("ik2213 assignment 2");
		
		strbuf = "IN IP4 " + hostAddr;
		setConnectionInformation(strbuf);

		setActiveTime("0 0");
		setSessionAttribute("direction:active");
		setMediaName("audio 48000 RTP/AVP 0");
		setMediaAttribute("direction:active");
		setMediaAttribute("rtpmap:0 PCMU/8000");
		setSDPbody();
		return SDPbody;
	}
	
	public String createSDPreply(){
		String strbuf = "";
		
		resetCount();
		generateID();
		setVersion("0");
		
		strbuf = "root " + theID + " " + theID + " IN IP4 " + hostAddr;
		setOriginator(strbuf);

		setSessionName("ik2213 assignment 2");
		
		strbuf = "IN IP4 " + hostAddr;
		setConnectionInformation(strbuf);

		setActiveTime("0 0");
		setSessionAttribute("direction:active");
		setMediaName("audio 48000 RTP/AVP 0");
		setMediaAttribute("direction:active");
		setMediaAttribute("rtpmap:0 PCMU/8000");
		setSDPbody();
		return SDPbody;
	}

}


